package com.imooc.miaoshaproject.controller;

import com.imooc.miaoshaproject.controller.viewobject.UserVO;
import com.imooc.miaoshaproject.exceptions.ErrorCodeEnum;
import com.imooc.miaoshaproject.exceptions.ServiceException;
import com.imooc.miaoshaproject.response.R;
import com.imooc.miaoshaproject.service.UserService;
import com.imooc.miaoshaproject.service.model.UserModel;
import org.springframework.beans.BeanUtils;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

/**
 * 用户接口
 *
 * @author chenjianfei
 */
@Controller("user")
@RequestMapping("/user")
@CrossOrigin(allowCredentials = "true", allowedHeaders = "*")
public class UserController extends BaseController {

    private final UserService userService;

    private final HttpServletRequest httpServletRequest;

    public UserController(UserService userService, HttpServletRequest httpServletRequest) {
        this.userService = userService;
        this.httpServletRequest = httpServletRequest;
    }

    /**
     * 根据ID获取用户信息
     *
     * @param id 用户编号
     * @return 用户信息
     * @throws ServiceException
     */
    @RequestMapping("/get")
    @ResponseBody
    public R getUserById(@RequestParam(name = "id") Integer id) throws ServiceException {
        UserModel userModel = userService.getUserById(id);
        if (userModel == null) {
            throw new ServiceException(ErrorCodeEnum.USER_NOT_EXIST);
        }
        UserVO userVO = convertFromModel(userModel);
        return R.create(userVO);
    }

    /**
     * 用户注册接口
     *
     * @param telphone
     * @param otpCode
     * @param name
     * @param gender
     * @param age
     * @param password
     * @return
     * @throws ServiceException
     * @throws UnsupportedEncodingException
     * @throws NoSuchAlgorithmException
     */
    @RequestMapping(value = "/register", method = {RequestMethod.POST}, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public R register(@RequestParam(name = "telphone") String telphone,
                      @RequestParam(name = "otpCode") String otpCode,
                      @RequestParam(name = "name") String name,
                      @RequestParam(name = "gender") Integer gender,
                      @RequestParam(name = "age") Integer age,
                      @RequestParam(name = "password") String password) throws ServiceException, UnsupportedEncodingException, NoSuchAlgorithmException {

        String inSessionOtpCode = (String) this.httpServletRequest.getSession().getAttribute(telphone);
        if (!com.alibaba.druid.util.StringUtils.equals(otpCode, inSessionOtpCode)) {
            throw new ServiceException(ErrorCodeEnum.PARAMETER_VALIDATION_ERROR, "短信验证码不符合");
        }
        //用户的注册流程
        UserModel userModel = new UserModel();
        userModel.setName(name);
        userModel.setGender(new Byte(String.valueOf(gender.intValue())));
        userModel.setAge(age);
        userModel.setTelphone(telphone);
        userModel.setRegisterMode("byphone");
        userModel.setEncrptPassword(this.EncodeByMd5(password));
        userService.register(userModel);
        return R.create(null);
    }

    /**
     * MD5加密
     *
     * @param str
     * @return
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     */
    private String EncodeByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        //确定计算方法
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        BASE64Encoder base64en = new BASE64Encoder();
        //加密字符串
        return base64en.encode(md5.digest(str.getBytes("utf-8")));
    }


    /**
     * 用户获取otp短信接口
     *
     * @param telephone 手机号
     */
    @RequestMapping(value = "/getotp", method = {RequestMethod.POST}, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public R getOtp(@RequestParam(name = "telphone") String telphone) {
        Random random = new Random();
        int randomInt = random.nextInt(99999);
        randomInt += 10000;
        String otpCode = String.valueOf(randomInt);
        httpServletRequest.getSession().setAttribute(telphone, otpCode);
        System.out.println("telphone = " + telphone + " & otpCode = " + otpCode);
        return R.create(null);
    }


    /**
     * Model层转换为VO层
     *
     * @param userModel
     * @return
     */
    private UserVO convertFromModel(UserModel userModel) {
        if (userModel == null) {
            return null;
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(userModel, userVO);
        return userVO;
    }


    /**
     * 用户登陆接口
     *
     * @param telphone 手机号码
     * @param password 密码
     */
    @RequestMapping(value = "/login", method = {RequestMethod.POST}, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public R login(@RequestParam(name = "telphone") String telphone,
                   @RequestParam(name = "password") String password) throws ServiceException, UnsupportedEncodingException, NoSuchAlgorithmException {

        //入参校验
        if (org.apache.commons.lang3.StringUtils.isEmpty(telphone) ||
                StringUtils.isEmpty(password)) {
            throw new ServiceException(ErrorCodeEnum.PARAMETER_VALIDATION_ERROR);
        }

        //用户登陆服务,用来校验用户登陆是否合法
        UserModel userModel = userService.validateLogin(telphone, this.EncodeByMd5(password));
        //将登陆凭证加入到用户登陆成功的session内
        this.httpServletRequest.getSession().setAttribute("IS_LOGIN", true);
        this.httpServletRequest.getSession().setAttribute("LOGIN_USER", userModel);
        return R.create(null);
    }
}
